package model;

import java.util.ArrayList;
import java.util.List;

import util.SMSUtil;
import Repository.ERPRepository;
import Repository.Repository;
import Repository.RepositoryFactory;
import Repository.UserRepository;
import constants.SMSConstants;

public class ApproveRuleSelector implements RuleSelector {
	private Repository ruleRepository = RepositoryFactory
			.getRepository(SMSConstants.RULE);
	private SMSObject smsObject;

	public ApproveRuleSelector(SMSObject smsObject) {
		this.smsObject = smsObject;
	}

	public boolean processRuleRequest() {
		// System.out.println("Processing Rule Request....");
		Rule approveRule = getRule();
		// System.out.println("Got rule.."+ approveRule);
		return applyRule(approveRule);
	}

	public Rule getRule() {

		// This if is for fetching approve rules for contract & opportunity and
		// qualify leads.
		// We pass an SMS Object and check its type and state to find the rule
		// to retrieve
		if (smsObject instanceof Lead
				&& smsObject.getCurrentState() instanceof Prepared) {
			return (Rule) ruleRepository.retrieve(SMSConstants.LEAD,
					SMSConstants.QUALIFY);
		} else // This is for fetching approve quotes rules for opportunity
		if (smsObject instanceof Opportunity
				&& smsObject.getCurrentState() instanceof Quoted) {
			return (Rule) ruleRepository.retrieve(SMSConstants.OPPORTUNITY,
					SMSConstants.APPROVE);
		} else // This is for fetching approve rules for contract
		if (smsObject instanceof Contract
				&& smsObject.getCurrentState() instanceof Prepared) {
			return (Rule) ruleRepository.retrieve(SMSConstants.CONTRACT,
					SMSConstants.APPROVE);
		}
		return new NullRule();
	}

	private boolean applyRule(Rule rule) {
		String criteria = rule.getRuleDescripton();

		// System.out.println("Applying Approval Rules...");

		if (smsObject instanceof Lead) {
			Lead objLead = (Lead) smsObject;
			if (objLead.getProductInterest().toLowerCase().toLowerCase()
					.contains(criteria)) {
				return true;
			}

		} else if (smsObject instanceof Opportunity) {
			Opportunity objOpportunity = (Opportunity) smsObject;
			if (smsObject.getCurrentState() instanceof Quoted) {
				if (criteria.toLowerCase().equalsIgnoreCase(
						"difference less than 200")) {
					double quotedPrice = objOpportunity.getPrice();
					double erpPrice = ERPRepository
							.getPricingInfo(objOpportunity.getProductName());
					double diff = erpPrice - quotedPrice;

					if (Math.abs(diff) < 200) {
						return true;
					}
				}
			}
		} else if (smsObject instanceof Contract) {
			Contract objCon = (Contract) smsObject;
			String choice = null;
			long nextApprover = 0;
			long maxLevel;
			int chkLevel;
			Repository repository = RepositoryFactory
					.getRepository(SMSConstants.CONTRACT);

			maxLevel = objCon.getMaxLevel();
			chkLevel = objCon.getCurrentLevel();
			if (smsObject.getCurrentState() instanceof Prepared) {
				System.out
						.println("Are you sure you want to approve this contract? (Y/N)");
				choice = SMSUtil.getUserInput();

				if (choice.trim().equalsIgnoreCase("y")) {
					if (chkLevel != maxLevel-1) {
						
						System.out.println("Contract completed "+(objCon.getCurrentLevel()+1)+ " level(s) of approval. It has to be sent for next level of approval.");
						
						System.out
								.println("Please select an approver for the next level :");
						List approverList = objCon.getApprovers();

						List<User> Approvers = UserRepository.getUserList();

						List<User> approversAvail = new ArrayList();

						for (User user : Approvers) {
							if (!approverList.contains(user.getId())) {
								approversAvail.add(user);
							}
						}

						for (User u : approversAvail) {
							System.out.println(u);
						}

						nextApprover = Long.parseLong(SMSUtil.getUserInput());
						objCon.setNextApprover(nextApprover);
						repository.update(objCon.getSmsObjId(), objCon);
						
						System.out
						.println("Successfully assigned contract to next level.");
				

					}
					return true;

				}
			}
		}

		return false;
	}

}
